﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Indigo=System.ServiceModel.Security;

namespace Microsoft.Cryptography.WCF
{
    /// <summary>
    /// The class used for serializing and deserializing security tokens, security key identifiers 
    /// and security key identifier clauses defined in the WS-Security, WS-Trust and WS-SecureConversation specifications.
    /// This implementation extends the base class (<see cref="System.ServiceModel.Security.WSSecurityTokenSerializer"/>) to
    /// support RSA-Signatures with SHA-2 encryption in XML-Signatures by returning an instance of 
    /// <see cref="Microsoft.Cryptography.WCF.X509SecurityToken"/> instead  of 
    /// <see cref="System.IdentityModel.Tokens.X509SecurityToken"/> when reading a X509SecurityToken in the method 
    /// ReadTokenCore
    /// </summary>
    public class WSSecurityTokenSerializer : Indigo.WSSecurityTokenSerializer
    {
        /// <summary>
        /// The class used for serializing and deserializing security tokens, security key identifiers 
        /// and security key identifier clauses defined in the WS-Security, WS-Trust and WS-SecureConversation specifications.
        /// This implementation extends the base class (<see cref="System.ServiceModel.Security.WSSecurityTokenSerializer"/>) to
        /// support RSA-Signatures with SHA-2 encryption in XML-Signatures by returning an instance of 
        /// <see cref="Microsoft.Cryptography.WCF.X509SecurityToken"/> instead  of 
        /// <see cref="System.IdentityModel.Tokens.X509SecurityToken"/> when reading a X509SecurityToken in the method 
        /// ReadTokenCore
        /// </summary>
        /// <param name="serializer">The <see cref="System.ServiceModel.Security.WSSecurityTokenSerializer"/> which is used to initialize the new instance.</param>
        public WSSecurityTokenSerializer(Indigo.WSSecurityTokenSerializer serializer)
            : base(serializer.SecurityVersion, serializer.EmitBspRequiredAttributes)
        {
        }

        /// <summary>
        /// Reads the tokens using the specified <see cref="System.Xml.XmlReader"/> by using the method of the base class 
        /// (<see cref="System.ServiceModel.Security.WSSecurityTokenSerializer"/>). If the token is of type 
        /// <see cref="System.IdentityModel.Tokens.X509SecurityToken"/> a new instance of 
        /// <see cref="Microsoft.Cryptography.WCF.X509SecurityToken"/> will be returned instead.
        /// </summary>
        /// <param name="reader">The specified <see cref="System.Xml.XmlReader"/></param>
        /// <param name="tokenResolver">The <see cref="System.IdentityModel.Selectors.SecurityTokenResolver"/>.</param>
        /// <returns>Reads the tokens using the specified <see cref="System.Xml.XmlReader"/> by using the method of the base class 
        /// (<see cref="System.ServiceModel.Security.WSSecurityTokenSerializer"/>). If the token is of type 
        /// <see cref="System.IdentityModel.Tokens.X509SecurityToken"/> a new instance of 
        /// <see cref="Microsoft.Cryptography.WCF.X509SecurityToken"/> will be returned instead.</returns>
        protected override System.IdentityModel.Tokens.SecurityToken ReadTokenCore(System.Xml.XmlReader reader, System.IdentityModel.Selectors.SecurityTokenResolver tokenResolver)
        {
            System.IdentityModel.Tokens.SecurityToken token =  base.ReadTokenCore(reader, tokenResolver);

            if (token is System.IdentityModel.Tokens.X509SecurityToken)
            {
                return new X509SecurityToken(((System.IdentityModel.Tokens.X509SecurityToken)token).Certificate,
                    ((System.IdentityModel.Tokens.X509SecurityToken)token).Id);
            }
            else
            {
                return token;
            }
        }

        
    }
}
